package com.example.dicos.util;

import cn.hutool.core.util.RandomUtil;
import com.google.common.collect.Maps;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.text.SimpleDateFormat;
import java.util.*;

@Component
public class FileUpload {
    //    @Value("${aliyun.oss.imgUrl}")
//    private  String fileWritePath;
    private static final Logger logger = LoggerFactory.getLogger(FileUpload.class);

    private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");

    private static final SimpleDateFormat sDateFormat = new SimpleDateFormat("mmss");

    //定义图片存储的路径
    public HashMap<String, Object> upload(MultipartFile[] files, String diskUrl, String imgUrl) {
        HashMap<String, Object> hashMap = Maps.newHashMap();
        String[] visitPathArr = new String[files.length];

        String writePath;
        String visitPath;
        // files是一个或者多个文件对象
        for (int i = 0; i < files.length; i++) {
            MultipartFile file = files[i];
            // 获取上传的文件名, 用来获取后缀名
            String originalFilename = file.getOriginalFilename();
            if (originalFilename == null) {
                continue;
            }
            // 文件输入流  实际就是文件内容
            try {
                InputStream inputStream = file.getInputStream();
                // 写入硬盘的名字
                String randomFileName = getRandomFileName();
//                String[] uuids = UUID.randomUUID().toString().split("-");
//                StringBuilder uuid = new StringBuilder();
//                for (String str : uuids) {
//                    uuid.append(str).append("/");
//                }
                String uuid = UUID.randomUUID().toString().replace("-", "");
                String writeFileName = randomFileName + "." + FilenameUtils.getExtension(originalFilename);
                // 获取当前的年月日
                String yyyyMMdd = sdf.format(new Date());
                // 这是访问路径
                visitPath = "/img" + "/" + yyyyMMdd + "/" + "original/" + uuid + "_" + writeFileName;
                // 准入写入硬盘的全路径 return writePath
//                writePath = imgUrl + visitPath;
//                writePath = diskUrl + imgUrl + visitPath;
                writePath = imgUrl + visitPath;
                File writeFile = new File(writePath);
                if (!writeFile.getParentFile().exists()) {
                    // 如果父目录不存在则创建父目录
                    if (!writeFile.getParentFile().mkdirs()) {
                        logger.error("文件上传出错");
                        return null;
                    }
                }
                FileOutputStream fos = new FileOutputStream(writeFile);
                // 将上传的流写入到 硬盘
                IOUtils.copy(inputStream, fos);
                IOUtils.close(inputStream);
                IOUtils.close(fos);
                //返回路径 服务器ip+文件生成url
                visitPathArr[i] = diskUrl + visitPath;
//                visitPathArr[i] = writePath;
            } catch (IOException e) {
                logger.error("文件上传出错", e);
                return null;
            }
        }
        List<String> list = Arrays.asList(visitPathArr);
        hashMap.put("original", list);
        List<String> img = yaSuo(files, diskUrl, imgUrl);
        hashMap.put("compress", img);
        return hashMap;
    }

    /**
     * 图片压缩
     * files 文件
     * diskUrl 保存路径
     * imgUrl  图片路径
     */
    public static List<String> yaSuo(MultipartFile[] files, String diskUrl, String imgUrl) {
        String[] visitPathArr = new String[files.length];
        String writePath;
        String visitPath;
        // files是一个或者多个文件对象
        for (int i = 0; i < files.length; i++) {
            MultipartFile file = files[i];
            // 获取上传的文件名, 用来获取后缀名
            String originalFilename = file.getOriginalFilename();
            if (originalFilename == null) {
                continue;
            }
            // 文件输入流  实际就是文件内容
            try {
                InputStream inputStream = file.getInputStream();
                String randomFileName = getRandomFileName();
//                           String[] uuids = UUID.randomUUID().toString().split("-");
//                StringBuilder uuid = new StringBuilder();
//                for (String str : uuids) {
//                    uuid.append(str).append("/");
//                }
                String uuid = UUID.randomUUID().toString().replace("-", "");
                // 写入硬盘的名字
                String writeFileName = randomFileName + "." + FilenameUtils.getExtension(originalFilename);
                // 获取当前的年月日
                String yyyyMMdd = sdf.format(new Date());
                // 这是访问路径
                visitPath = "/img" + "/" + yyyyMMdd + "/" + "compress/" + uuid + writeFileName;
                // 准入写入硬盘的全路径 return writePath
//                writePath = diskUrl + imgUrl + visitPath;
                writePath = imgUrl + visitPath;
                File writeFile = new File(writePath);
                if (!writeFile.getParentFile().exists()) {
                    // 如果父目录不存在则创建父目录
                    if (!writeFile.getParentFile().mkdirs()) {
                        logger.error("文件上传出错");
                        return null;
                    }
                }
                FileOutputStream fos = new FileOutputStream(writeFile);
                // 将上传的流写入到 硬盘
                IOUtils.copy(inputStream, fos);
                IOUtils.close(inputStream);
                IOUtils.close(fos);
                visitPathArr[i] = diskUrl + visitPath;
//                visitPathArr[i] = writePath;
                //压缩图片到指定120K以内,不管你的图片有多少兆,都不会超过120kb
                // 递归压缩，直到目标文件大小小于desFileSize
//                byte[] bytes = PicUtils.compressPicCycle(file.getBytes(), 120);
//                byte[] bytes = PicUtils.imageSet(file.getBytes(),120);
                byte[] bytes = PicUtils.compressPicForScale(file.getBytes(), 120);
                //生成保存在服务器的图片名称，统一修改原后缀名为:jpg
                File fOut = new File(writePath);
                FileOutputStream fileOutputStream = new FileOutputStream(fOut);
                fileOutputStream.write(bytes);
                fileOutputStream.close();
            } catch (IOException e) {
                logger.error("文件上传出错", e);
                return null;
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return Arrays.asList(visitPathArr);
    }


    /**
     * 下载图片
     * urlString 图片原地址链接
     * path 保存地址
     */
    public static String download(String urlString, String path) throws Exception {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        // 构造URL
        URL url = new URL(urlString);
        // 打开连接
        URLConnection con = url.openConnection();
        // 输入流
        InputStream is = con.getInputStream();
        // 1K的数据缓冲
        byte[] bs = new byte[1024];
        // 读取到的数据长度
        int len;
        // 写入硬盘的名字
        String uuid = UUID.randomUUID().toString().replace("-", "");
        // 获取当前的年月日
        String yyyyMMdd = sdf.format(new Date());
        // 这是访问路径
        String visitPath = path + "/" + yyyyMMdd + "/" + uuid;
        // 输出的文件流
        String filename = visitPath + ".jpg";  //下载路径及下载图片名称
        File file = new File(filename);
        if (!file.getParentFile().exists()) {
            // 如果父目录不存在则创建父目录
            file.getParentFile().mkdirs();
        }
        FileOutputStream os = new FileOutputStream(file, true);
        // 开始读取
        while ((len = is.read(bs)) != -1) {
            os.write(bs, 0, len);
        }
        System.out.println(path);
        // 完毕，关闭所有链接
        os.close();
        is.close();
        return file.getCanonicalPath();
    }

    /**
     * 生成随机文件名，当前年月日小时分钟秒+五位随机数
     */
    public static String getRandomFileName() {
        // 当前时间
        return sDateFormat.format(new Date()) + RandomUtil.randomStringUpper(4);
    }

}
